merge

Andrew Cantino 11 years ago
parent
commit
f8ee5e3ec4

+ 6 - 3
app/assets/javascripts/application.js.coffee.erb

@@ -99,9 +99,12 @@ $(document).ready ->
99 99
         $("#logs .spinner").stop(true, true).fadeOut ->
100 100
           $("#logs .refresh, #logs .clear").show()
101 101
 
102
-  $(".agent-show #show-tabs a[href='#logs']").on "click", fetchLogs
103
-  $("#logs .refresh").on "click", fetchLogs
104
-  $("#logs .clear").on "click", clearLogs
102
+  $(".agent-show #show-tabs a[href='#logs'], #logs .refresh").on "click", fetchLogs
103
+  $(".agent-show #logs .clear").on "click", clearLogs
104
+
105
+  if tab = window.location.href.match(/tab=(\w+)\b/i)?[1]
106
+    if tab in ["details", "logs"]
107
+      $(".agent-show .nav-tabs li a[href='##{tab}']").click()
105 108
 
106 109
   # Editing Agents
107 110
   $("#agent_source_ids").on "change", showEventDescriptions

+ 6 - 1
app/assets/stylesheets/application.css.scss.erb

@@ -82,6 +82,11 @@ img.spinner {
82 82
   overflow: hidden;
83 83
 }
84 84
 
85
+span.not-applicable:after {
86
+  color: #bbbbbb;
87
+  content: "n/a";
88
+}
89
+
85 90
 // Navbar
86 91
 
87 92
 #job-indicator, #event-indicator {
@@ -116,4 +121,4 @@ img.spinner {
116 121
   &.refresh {
117 122
     margin: 0 10px;
118 123
   }
119
-}
124
+}

+ 1 - 1
app/helpers/application_helper.rb

@@ -11,7 +11,7 @@ module ApplicationHelper
11 11
     if agent.working?
12 12
       '<span class="label label-success">Yes</span>'.html_safe
13 13
     else
14
-      '<span class="label label-warning">No</span>'.html_safe
14
+      link_to '<span class="label label-warning">No</span>'.html_safe, agent_path(agent, :tab => (agent.recent_error_logs? ? 'logs' : 'details'))
15 15
     end
16 16
   end
17 17
 end

+ 22 - 2
app/models/agent.rb

@@ -88,7 +88,11 @@ class Agent < ActiveRecord::Base
88 88
   end
89 89
 
90 90
   def create_event(attrs)
91
-    events.create!({ :user => user }.merge(attrs))
91
+    if can_create_events?
92
+      events.create!({ :user => user }.merge(attrs))
93
+    else
94
+      error "This Agent cannot create events!"
95
+    end
92 96
   end
93 97
 
94 98
   def validate_schedule
@@ -117,7 +121,7 @@ class Agent < ActiveRecord::Base
117 121
   end
118 122
 
119 123
   def last_event_at
120
-    @memoized_last_event_at ||= events.select(:created_at).first.try(:created_at)
124
+    @memoized_last_event_at ||= most_recent_event.try(:created_at)
121 125
   end
122 126
 
123 127
   def default_schedule
@@ -140,6 +144,14 @@ class Agent < ActiveRecord::Base
140 144
     !cannot_receive_events?
141 145
   end
142 146
 
147
+  def cannot_create_events?
148
+    self.class.cannot_create_events?
149
+  end
150
+
151
+  def can_create_events?
152
+    !cannot_create_events?
153
+  end
154
+
143 155
   def set_last_checked_event_id
144 156
     if newest_event_id = Event.order("id desc").limit(1).pluck(:id).first
145 157
       self.last_checked_event_id = newest_event_id
@@ -169,6 +181,14 @@ class Agent < ActiveRecord::Base
169 181
       @default_schedule
170 182
     end
171 183
 
184
+    def cannot_create_events!
185
+      @cannot_create_events = true
186
+    end
187
+
188
+    def cannot_create_events?
189
+      !!@cannot_create_events
190
+    end
191
+
172 192
     def cannot_receive_events!
173 193
       @cannot_receive_events = true
174 194
     end

+ 2 - 0
app/models/agents/digest_email_agent.rb

@@ -3,6 +3,8 @@ module Agents
3 3
     MAIN_KEYS = %w[title message text main value].map(&:to_sym)
4 4
     default_schedule "5am"
5 5
 
6
+    cannot_create_events!
7
+
6 8
     description <<-MD
7 9
       The DigestEmailAgent collects any Events sent to it and sends them all via email when run.
8 10
       The email will be sent to your account's address and will have a `subject` and an optional `headline` before

+ 1 - 0
app/models/agents/post_agent.rb

@@ -1,6 +1,7 @@
1 1
 module Agents
2 2
   class PostAgent < Agent
3 3
     cannot_be_scheduled!
4
+    cannot_create_events!
4 5
 
5 6
     description <<-MD
6 7
        Post Agent receives events from other agents and send those events as the contents of a post request to a specified url. `post_url` field must specify where you would like to receive post requests and do not forget to include URI scheme (`http` or `https`)

+ 1 - 0
app/models/agents/twilio_agent.rb

@@ -4,6 +4,7 @@ require 'securerandom'
4 4
 module Agents
5 5
   class TwilioAgent < Agent
6 6
     cannot_be_scheduled!
7
+    cannot_create_events!
7 8
 
8 9
     description <<-MD
9 10
       The TwilioAgent receives and collects events and sends them via text message or gives you a call when scheduled.

+ 2 - 1
app/views/agents/_form.html.erb

@@ -47,8 +47,9 @@
47 47
   <div class="control-group">
48 48
     <%= f.label :sources, :class => 'control-label' %>
49 49
     <div class="controls link-region" data-can-receive-events="<%= @agent.can_receive_events? %>">
50
+      <% eventSources = (current_user.agents - [@agent]).find_all { |a| a.can_create_events? } %>
50 51
       <%= f.select(:source_ids,
51
-                   options_for_select((current_user.agents - [@agent]).map {|s| [s.name, s.id] },
52
+                   options_for_select(eventSources.map {|s| [s.name, s.id] },
52 53
                                       @agent.source_ids),
53 54
                    {}, { :multiple => true, :size => 5, :class => 'span4 select2' }) %>
54 55
       <span class='cannot-receive-events text-info'>This type of Agent cannot receive events.</span>

+ 55 - 37
app/views/agents/index.html.erb

@@ -8,53 +8,71 @@
8 8
       <table class='table table-striped'>
9 9
         <tr>
10 10
           <th>Name</th>
11
+          <th>Schedule</th>
11 12
           <th>Last Check</th>
12 13
           <th>Last Event Out</th>
13 14
           <th>Last Event In</th>
14
-          <th>Events</th>
15
-          <th>Schedule</th>
15
+          <th>Events Created</th>
16 16
           <th>Working?</th>
17 17
           <th></th>
18 18
         </tr>
19 19
 
20 20
         <% @agents.each do |agent| %>
21
-            <tr>
22
-              <td>
23
-                <%= agent.name %>
24
-                <br/>
25
-                <span class='muted'><%= agent.short_type.titleize %></span>
26
-              </td>
27
-              <td>
28
-                <% if agent.cannot_be_scheduled? %>
29
-                    N/A
30
-                <% else %>
31
-                    <%= agent.last_check_at ? time_ago_in_words(agent.last_check_at) + " ago" : "never" %>
32
-                <% end %>
33
-              </td>
34
-              <td><%= agent.last_event_at ? time_ago_in_words(agent.last_event_at) + " ago" : "never" %></td>
35
-              <td>
36
-                <% if agent.cannot_receive_events? %>
37
-                    N/A
21
+          <tr>
22
+            <td>
23
+              <%= agent.name %>
24
+              <br/>
25
+              <span class='muted'><%= agent.short_type.titleize %></span>
26
+            </td>
27
+            <td>
28
+              <% if agent.can_be_scheduled? %>
29
+                <%= agent.schedule.to_s.humanize.titleize %>
30
+              <% else %>
31
+                <span class='not-applicable'></span>
32
+              <% end %>
33
+            </td>
34
+            <td>
35
+              <% if agent.can_be_scheduled? %>
36
+                <%= agent.last_check_at ? time_ago_in_words(agent.last_check_at) + " ago" : "never" %>
37
+              <% else %>
38
+                <span class='not-applicable'></span>
39
+              <% end %>
40
+            </td>
41
+            <td>
42
+              <% if agent.can_create_events? %>
43
+                <%= agent.last_event_at ? time_ago_in_words(agent.last_event_at) + " ago" : "never" %>
44
+              <% else %>
45
+                <span class='not-applicable'></span>
46
+              <% end %>
47
+            </td>
48
+            <td>
49
+              <% if agent.can_receive_events? %>
50
+                <%= agent.last_receive_at ? time_ago_in_words(agent.last_receive_at) + " ago" : "never" %>
51
+              <% else %>
52
+                <span class='not-applicable'></span>
53
+              <% end %>
54
+            </td>
55
+            <td>
56
+              <% if agent.can_create_events? %>
57
+                <%= link_to(agent.events_count || 0, events_path(:agent => agent.to_param)) %>
58
+              <% else %>
59
+                <span class='not-applicable'></span>
60
+              <% end %>
61
+            </td>
62
+            <td><%= working(agent) %></td>
63
+            <td>
64
+              <div class="btn-group">
65
+                <%= link_to 'Show', agent_path(agent), class: "btn btn-mini" %>
66
+                <%= link_to 'Edit', edit_agent_path(agent), class: "btn btn-mini" %>
67
+                <%= link_to 'Delete', agent_path(agent), method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-mini" %>
68
+                <% if agent.can_be_scheduled? %>
69
+                  <%= link_to 'Run', run_agent_path(agent, :return => "index"), method: :post, class: "btn btn-mini" %>
38 70
                 <% else %>
39
-                    <%= agent.last_receive_at ? time_ago_in_words(agent.last_receive_at) + " ago" : "never" %>
71
+                  <%= link_to 'Run', "#", class: "btn btn-mini disabled" %>
40 72
                 <% end %>
41
-              </td>
42
-              <td><%= link_to(agent.events_count || 0, events_path(:agent => agent.to_param)) %></td>
43
-              <td><%= (agent.schedule || "n/a").to_s.humanize.titleize %></td>
44
-              <td><%= working(agent) %></td>
45
-              <td>
46
-                <div class="btn-group">
47
-                  <%= link_to 'Show', agent_path(agent), class: "btn btn-mini" %>
48
-                  <%= link_to 'Edit', edit_agent_path(agent), class: "btn btn-mini" %>
49
-                  <%= link_to 'Delete', agent_path(agent), method: :delete, data: {confirm: 'Are you sure?'}, class: "btn btn-mini" %>
50
-                  <% if agent.can_be_scheduled? %>
51
-                      <%= link_to 'Run', run_agent_path(agent, :return => "index"), method: :post, class: "btn btn-mini" %>
52
-                  <% else %>
53
-                      <%= link_to 'Run', "#", class: "btn btn-mini disabled" %>
54
-                  <% end %>
55
-                </div>
56
-              </td>
57
-            </tr>
73
+              </div>
74
+            </td>
75
+          </tr>
58 76
         <% end %>
59 77
       </table>
60 78
 

+ 50 - 28
app/views/agents/show.html.erb

@@ -13,7 +13,7 @@
13 13
           <% end %>
14 14
           <li><a href="#logs" data-toggle="tab" data-agent-id="<%= @agent.id %>"><i class='icon-list-alt'></i> Logs</a></li>
15 15
 
16
-          <% if @agent.events.count > 0 %>
16
+          <% if @agent.can_create_events? && @agent.events.count > 0 %>
17 17
             <li><%= link_to '<i class="icon-random"></i> Events'.html_safe, events_path(:agent => @agent.to_param) %></li>
18 18
           <% end %>
19 19
           <li><%= link_to '<i class="icon-chevron-left"></i> Back'.html_safe, agents_path %></li>
@@ -29,7 +29,7 @@
29 29
                   </li>
30 30
                 <% end %>
31 31
 
32
-                <% if @agent.events.count > 0 %>
32
+                <% if @agent.can_create_events? && @agent.events.count > 0 %>
33 33
                   <li>
34 34
                     <%= link_to '<i class="icon-trash"></i> Delete all events'.html_safe, remove_events_agent_path(@agent), method: :delete, data: {confirm: 'Are you sure you want to delete ALL events for this Agent?'}, :tabindex => "-1" %>
35 35
                   </li>
@@ -70,38 +70,60 @@
70 70
               <%= @agent.short_type.titleize %>
71 71
             </p>
72 72
 
73
-            <p>
74
-              <b>Schedule:</b>
75
-              <%= (@agent.schedule || "n/a").humanize.titleize %>
76
-            </p>
73
+            <% if @agent.can_be_scheduled? %>
74
+              <p>
75
+                <b>Schedule:</b>
76
+                <%= (@agent.schedule || "n/a").humanize.titleize %>
77
+              </p>
77 78
 
78
-            <p>
79
-              <b>Last checked:</b>
80
-              <% if @agent.cannot_be_scheduled? %>
81
-                N/A
82
-              <% else %>
79
+              <p>
80
+                <b>Last checked:</b>
83 81
                 <%= @agent.last_check_at ? time_ago_in_words(@agent.last_check_at) + " ago" : "never" %>
84
-              <% end %>
85
-            </p>
82
+              </p>
83
+            <% end %>
86 84
 
87
-            <p>
88
-              <b>Last event created:</b>
89
-              <%= @agent.last_event_at ? time_ago_in_words(@agent.last_event_at) + " ago" : "never" %>
90
-            </p>
85
+            <% if @agent.can_create_events? %>
86
+              <p>
87
+                <b>Last event created:</b>
88
+                <%= @agent.last_event_at ? time_ago_in_words(@agent.last_event_at) + " ago" : "never" %>
89
+              </p>
90
+            <% end %>
91 91
 
92
-            <p>
93
-              <b>Last received event:</b>
94
-              <% if @agent.cannot_receive_events? %>
95
-                N/A
96
-              <% else %>
92
+            <% if @agent.can_receive_events? %>
93
+              <p>
94
+                <b>Last received event:</b>
97 95
                 <%= @agent.last_receive_at ? time_ago_in_words(@agent.last_receive_at) + " ago" : "never" %>
98
-              <% end %>
99
-            </p>
96
+              </p>
97
+            <% end %>
100 98
 
101
-            <p>
102
-              <b>Event count:</b>
103
-              <%= link_to @agent.events.count, events_path(:agent => @agent.to_param) %>
104
-            </p>
99
+            <% if @agent.can_create_events? %>
100
+              <p>
101
+                <b>Events created:</b>
102
+                <%= link_to @agent.events.count, events_path(:agent => @agent.to_param) %>
103
+              </p>
104
+            <% end %>
105
+
106
+            <% if @agent.can_receive_events? %>
107
+              <p>
108
+                <b>Event sources:</b>
109
+                <% if @agent.sources.length %>
110
+                  <%= @agent.sources.map { |source_agent| link_to(source_agent.name, agent_path(source_agent)) }.to_sentence.html_safe %>
111
+                <% else %>
112
+                  None
113
+                <% end %>
114
+              </p>
115
+            <% end %>
116
+
117
+            <% if @agent.can_create_events? %>
118
+              <p>
119
+                <b>Event receivers:</b>
120
+                <% if @agent.receivers.length %>
121
+                  <%= @agent.receivers.map { |receiver_agent| link_to(receiver_agent.name, agent_path(receiver_agent)) }.to_sentence.html_safe %>
122
+                <% else %>
123
+                  None
124
+                <% end %>
125
+              </p>
126
+            <% end %>
105 127
 
106 128
             <p>
107 129
               <b>Working:</b>

+ 4 - 0
app/views/layouts/_navigation.html.erb

@@ -43,6 +43,10 @@
43 43
       </li>
44 44
 
45 45
       <li>
46
+        <%= link_to 'About', 'https://github.com/cantino/huginn', :tabindex => "-1" %>
47
+      </li>
48
+
49
+      <li>
46 50
         <% if user_signed_in? %>
47 51
           <%= link_to 'Logout', destroy_user_session_path, :method => :delete, :tabindex => "-1" %>
48 52
         <% else %>

+ 15 - 5
spec/models/agent_spec.rb

@@ -114,13 +114,23 @@ describe Agent do
114 114
     end
115 115
 
116 116
     describe "#create_event" do
117
+      before do
118
+        @checker = Agents::SomethingSource.new(:name => "something")
119
+        @checker.user = users(:bob)
120
+        @checker.save!
121
+      end
122
+
117 123
       it "should use the checker's user" do
118
-        checker = Agents::SomethingSource.new(:name => "something")
119
-        checker.user = users(:bob)
120
-        checker.save!
124
+        @checker.check
125
+        Event.last.user.should == @checker.user
126
+      end
121 127
 
122
-        checker.check
123
-        Event.last.user.should == checker.user
128
+      it "should log an error if the Agent has been marked with 'cannot_create_events!'" do
129
+        mock(@checker).can_create_events? { false }
130
+        lambda {
131
+          @checker.check
132
+        }.should_not change { Event.count }
133
+        @checker.logs.first.message.should =~ /cannot create events/i
124 134
       end
125 135
     end
126 136
 

+ 5 - 1
vendor/assets/stylesheets/jquery.json-editor.css.scss

@@ -52,8 +52,12 @@
52 52
     display: block;
53 53
     float: right;
54 54
     text-decoration: none;
55
-    padding-left: 5px;
55
+    padding: 0 5px;
56 56
     border: 0 !important;
57 57
     color: blue;
58
+
59
+    &:hover {
60
+      background-color: #bbb;
61
+    }
58 62
   }
59 63
 }